# code to generate listeners.py file
# useful URL: http://java.sun.com/developer/technicalArticles/ALT/Reflection/index.html

# list of all packages with classes definine EventListener subclasses
# Format:  java.packageName1 classA classB ... java.packageName2 classC classD ... 
# Note there are unused items afterwards -- wanted to make a complete list of those EventListener interfaces

from java.lang import Class

EventListenerSubclasses = """
java.awt.event
    ActionListener
    AdjustmentListener
    AWTEventListener
    ComponentListener
    ContainerListener
    FocusListener
    HierarchyBoundsListener
    HierarchyListener
    InputMethodListener
    ItemListener
    KeyListener 
    MouseListener
    MouseMotionListener
    MouseWheelListener
    TextListener
    WindowFocusListener
    WindowListener
    WindowStateListener
    
java.awt.dnd
    DragGestureListener
    DragSourceListener
    DragSourceMotionListener
    DropTargetListener
    
javax.swing.event
    AncestorListener
    CaretListener
    CellEditorListener
    ChangeListener
    DocumentListener
    HyperlinkListener
    InternalFrameListener
    ListDataListener
    ListSelectionListener
    MenuDragMouseListener
    MenuKeyListener
    MenuListener
    MouseInputListener
    PopupMenuListener
    TableColumnModelListener
    TableModelListener
    TreeExpansionListener
    TreeModelListener
    TreeSelectionListener
    TreeWillExpandListener
    UndoableEditListener
    
"""

UNUSED = """

javax.swing
    Action
    
java.beans
    ExceptionListener
    PropertyChangeListener
    VetoableChangeListener
    
java.beans.beancontext
    BeanContextMembershipListener
    BeanContextServiceRevokedListener
    BeanContextServices
    BeanContextServicesListener
    
java.util.prefs
    NodeChangeListener
    PreferenceChangeListener
  
javax.imageio.event
    IIOReadProgressListener
    IIOReadUpdateListener
    IIOReadWarningListener
    IIOWriteProgressListener
    IIOWriteWarningListener
 
javax.naming.event
    NamespaceChangeListener
    NamingListener
    ObjectChangeListener
    
javax.sql
    ConnectionEventListener
    RowSetListener
     
javax.sound.midi
    ControllerEventListener
    MetaEventListener

javax.net.ssl
    HandshakeCompletedListener
    SSLSessionBindingListener

javax.naming.ldap
    UnsolicitedNotificationListener

javax.sound.sampled
    LineListener
    
"""

Preamble = """# listeners.py
# NOTE: This file is generated by listeners_generateFile.py
# ANY CHANGES HERE WILL BE LOST THE NEXT TIME THIS FILE IS REGENERATED

from listeners_support import DispatchEventForPath

# A list of all these listeners, each which has metadata about its names and fields
AllDynamicListenerClasses = []

"""

def GenerateFile(fileName="listeners.py"):
    print "Rewriting listener file: %s" %  fileName
    outputFile = open(fileName, "w")

    outputFile.write(Preamble)
    
    items = EventListenerSubclasses.split()
    for item in items:
        # support commenting out an individual class
        if item[0] == "#":
            print "SKIPPING", item
            continue
        if item.find(".") != -1:
            print "\nPACKAGE", item
            packageName = item
            continue
        listenerClassName = item
        dynamicClassName =  "Dynamic%s" % listenerClassName
        print "    Generating ", dynamicClassName, "for", listenerClassName
        theClass = Class.forName(packageName + "." + listenerClassName)
        methods = theClass.declaredMethods
        methodNames = []
        for method in methods:
            methodNames.append(method.name)
            parameterTypes = method.parameterTypes
            if len(parameterTypes) != 1:
                raise "should have exactly one argument: %s %s " % (listenerClassName, method.name)
            typeName = "%s" % parameterTypes[0]
            if typeName.find("Event") == -1:
                raise "parameter type name %s does not included Event for %s %s " % (typeName, listenerClassName, method.name)
        
        outputFile.write("from %s import %s\n" % (packageName, listenerClassName))
        outputFile.write("class %s(%s):\n" % (dynamicClassName, listenerClassName))
        outputFile.write('    packageForListenerClass = "%s"\n' % packageName)
        outputFile.write('    listenerClassName = "%s"\n' % listenerClassName)
        outputFile.write('    dynamicClassName = "%s"\n' % dynamicClassName)
        fieldNameString = "    fieldNames = ("
        for methodName in methodNames:
            fieldNameString += '"%s", ' % methodName
        fieldNameString += ")\n"
        outputFile.write(fieldNameString)
        outputFile.write("\n")
        argString = ""
        for methodName in methodNames:
            argString = argString + '%s="", ' % methodName
        outputFile.write('    def __init__(self, %smodel=None):\n' % argString)
        outputFile.write("        self.model = model\n")
        for methodName in methodNames:
            outputFile.write("        self.%sPathSpecification = %s\n" % (methodName, methodName))   
        outputFile.write("\n")
        for methodName in methodNames:
            outputFile.write("    def %s(self, event):\n" % methodName)
            outputFile.write("        DispatchEventForPath(event, self.model, self.%sPathSpecification)\n" % methodName)
            outputFile.write("\n")
        outputFile.write("AllDynamicListenerClasses.append(%s)\n" % dynamicClassName)
        outputFile.write("\n")
        
    outputFile.close() 
    
    print "\ntesting it by importing"
    import listeners
    
    print "done"
    
if __name__ == "__main__":
    GenerateFile()